﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YArchitech.Revit;

namespace YJKArch.DoorWinModule
{
	internal class MirrorOperater
	{
		public static List<Element> MirrorElement(Autodesk.Revit.DB.Document document, Element element, Plane plane, bool isCopy)
		{
			int elementCount = MirrorOperater.GetElementCount(document);
			ElementTransformUtils.MirrorElement(document, element.Id, plane);
			List<Element> elementsAfter = MirrorOperater.GetElementsAfter(elementCount, document);
			if (elementsAfter.Count < 1)
			{
				return null;
			}
			for (int i = 0; i < elementsAfter.Count; i++)
			{
				Element element2 = elementsAfter[i];
				MirrorOperater.CopyParameters(element, ref element2);
			}
			if (!isCopy)
			{
				document.Delete(element.Id);
			}
			return elementsAfter;
		}

		public static FamilyInstance MirrorParasiticElement(Autodesk.Revit.DB.Document document, FamilyInstance instance, Plane plane, bool isCopy)
		{
			double value = 0.0;
			bool sillHeightParam = MirrorOperater.GetSillHeightParam(instance, ref value);
			if (sillHeightParam)
			{
				MirrorOperater.SetSillHeightParam(ref instance, 0.0);
			}
			int elementCount = MirrorOperater.GetElementCount(document);
			ElementTransformUtils.MirrorElement(document, instance.Id, plane);
			List<Element> elementsAfter = MirrorOperater.GetElementsAfter(elementCount, document);
			if (elementsAfter.Count < 1)
			{
				return null;
			}
			FamilyInstance result = elementsAfter[0] as FamilyInstance;
			if (sillHeightParam)
			{
				MirrorOperater.SetSillHeightParam(ref result, value);
				MirrorOperater.SetSillHeightParam(ref instance, value);
			}
			MirrorOperater.CopyParameters(instance, ref result);
			if (!isCopy)
			{
				document.DeleteElement(instance);
			}
			return result;
		}

		private static FilteredElementCollector GetElements(Autodesk.Revit.DB.Document document)
		{
			return new FilteredElementCollector(document).WhereElementIsNotElementType();
		}

		private static int GetElementCount(Autodesk.Revit.DB.Document document)
		{
			return MirrorOperater.GetElements(document).ToElements().Count;
		}

		private static List<Element> GetElementsAfter(int n, Autodesk.Revit.DB.Document document)
		{
			List<Element> list = new List<Element>();
			FilteredElementCollector elements = MirrorOperater.GetElements(document);
			int num = 0;
			foreach (Element item in elements)
			{
				num++;
				if (n < num)
				{
					list.Add(item);
				}
			}
			return list;
		}

		private static bool GetSillHeightParam(FamilyInstance instance, ref double value)
		{
			Parameter parameter = instance.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM);
			if (parameter == null)
			{
				return false;
			}
			value = parameter.AsDouble();
			return true;
		}

		private static void SetSillHeightParam(ref FamilyInstance instance, double value)
		{
			instance.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM).Set(value);
		}

		public static void CopyParameters(Element element, ref Element newElement)
		{
			foreach (object obj in element.Parameters)
			{
				Parameter parameter = (Parameter)obj;
				if (!parameter.IsReadOnly && parameter.HasValue && parameter.IsShared)
				{
					switch ((int)parameter.StorageType)
					{
					case 1:
						newElement.get_Parameter(parameter.GUID).Set(parameter.AsInteger());
						break;
					case 2:
						newElement.get_Parameter(parameter.GUID).Set(parameter.AsDouble());
						break;
					case 3:
						newElement.get_Parameter(parameter.GUID).Set(parameter.AsString());
						break;
					}
				}
			}
		}

		public static void CopyParameters(FamilyInstance instance, ref FamilyInstance newInstance)
		{
			Element element = newInstance;
			MirrorOperater.CopyParameters(instance, ref element);
		}
	}
}
